﻿using Demo.Identity.Permissions;
using Microsoft.AspNetCore.Http.Features;
using Volo.Abp.Users;

namespace Demo.Permissions;

/// <summary>
/// 自定义权限中间件
/// </summary>
public class CusPermissionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ICurrentUser _currentUser;
    private readonly ISysPermissionAppService _service;

    public CusPermissionMiddleware(RequestDelegate next, ICurrentUser currentUser, ISysPermissionAppService service)
    {
        _next = next;
        _currentUser = currentUser;
        _service = service;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var attributes = 
            context.GetEndpoint()?.Metadata.GetOrderedMetadata<CusPermissionAttribute>();
        
        //如果不存在CusPermissionAttribute特性则该接口不需要权限验证，直接跳过
        if (attributes==null||attributes.Count==0)
        {
            await _next(context);
            return;
        }
        //如果需要权限验证则必须是已登录用户，否则返回401
        if (_currentUser.Id == null)
        {
            context.Response.StatusCode = 401;
            return;
        }
        //获取用户权限
        var userPermisions = (await _service.GetUserPermissionCode((Guid) _currentUser.Id)).ToHashSet();
        //比对权限 如果无权限则返回403
        foreach (var cusPermissionAttribute in attributes)
        {
            var flag = cusPermissionAttribute.Relation == PermissionRelation.And
                ? cusPermissionAttribute.PermissionCode.All(code => userPermisions.Contains(code))
                : cusPermissionAttribute.PermissionCode.Any(code => userPermisions.Contains(code));
            if (!flag)
            {
                context.Response.StatusCode = 403;
                return;
            }
        }

        await _next(context);
    }
}